﻿using Microsoft.Extensions.Caching.Distributed;
using System.Diagnostics.CodeAnalysis;

namespace Niaofei.Redis;

public interface IDistributedCache<TCacheItem> : IDistributedCache<TCacheItem, string>
    where TCacheItem : class
{
    IDistributedCache<TCacheItem, string> InternalCache { get; }
}

public interface IDistributedCache<TCacheItem, TCacheKey>
    where TCacheItem : class
{
    /// <summary>
    /// 获取单个Redis值
    /// </summary>
    /// <param name="key">redis key</param>
    TCacheItem? Get(
        TCacheKey key
    );

    /// <summary>
    /// 获取多个Redis值
    /// </summary>
    /// <param name="keys">redis keys</param>
    KeyValuePair<TCacheKey, TCacheItem>[] GetMany(
        IEnumerable<TCacheKey> keys
    );

    /// <summary>
    /// 获取多个Redis值
    /// </summary>
    /// <param name="keys">redis key</param>
    Task<KeyValuePair<TCacheKey, TCacheItem>[]> GetManyAsync(
        IEnumerable<TCacheKey> keys,
        CancellationToken token = default
    );

    /// <summary>
    /// 获取单个Redis值
    /// </summary>
    /// <param name="key">redis key</param>
    Task<TCacheItem?> GetAsync(
        TCacheKey key,
        CancellationToken token = default
    );

    /// <summary>
    /// 获取一个Redis值,如果没有就添加
    /// </summary>
    /// <param name="key">redis key</param>
    /// <param name="factory">没有值时需要添加的Redis值</param>
    /// <param name="optionsFactory">Redis 添加时设置</param>
    /// <returns></returns>
    TCacheItem GetOrAdd(
        TCacheKey key,
        Func<TCacheItem> factory,
        Func<DistributedCacheEntryOptions>? optionsFactory = null
    );

    /// <summary>
    /// 获取一个Redis值,如果没有就添加
    /// </summary>
    /// <param name="key">redis key</param>
    /// <param name="factory">没有值时需要添加的Redis值</param>
    /// <param name="optionsFactory">Redis 添加时设置</param>
    Task<TCacheItem> GetOrAddAsync(
        TCacheKey key,
        Func<Task<TCacheItem>> factory,
        Func<DistributedCacheEntryOptions>? optionsFactory = null,
        CancellationToken token = default
    );

    /// <summary>
    /// 获取多个Redis值,如果没有就添加
    /// </summary>
    /// <param name="keys">reids keys</param>
    /// <param name="factory">没有值时需要添加的Redis值</param>
    /// <param name="optionsFactory">Redis 添加时设置</param>
    KeyValuePair<TCacheKey, TCacheItem>[] GetOrAddMany(
        IEnumerable<TCacheKey> keys,
        Func<IEnumerable<TCacheKey>, List<KeyValuePair<TCacheKey, TCacheItem>>> factory,
        Func<DistributedCacheEntryOptions>? optionsFactory = null
    );

    /// <summary>
    /// 获取多个Redis值,如果没有就添加
    /// </summary>
    /// <param name="keys">reids keys</param>
    /// <param name="factory">没有值时需要添加的Redis值</param>
    /// <param name="optionsFactory">Redis 添加时设置</param>
    Task<KeyValuePair<TCacheKey, TCacheItem>[]> GetOrAddManyAsync(
        IEnumerable<TCacheKey> keys,
        Func<IEnumerable<TCacheKey>, Task<List<KeyValuePair<TCacheKey, TCacheItem>>>> factory,
        Func<DistributedCacheEntryOptions>? optionsFactory = null,
        CancellationToken token = default
    );

    /// <summary>
    /// redis单个添加
    /// </summary>
    /// <param name="key">redis key</param>
    /// <param name="value">redis value</param>
    /// <param name="options">Redis设置</param>
    void Set(
        TCacheKey key,
        TCacheItem value,
        DistributedCacheEntryOptions? options = null
    );

    /// <summary>
    /// redis单个添加
    /// </summary>
    /// <param name="key">redis key</param>
    /// <param name="value">redis value</param>
    /// <param name="options">Redis设置</param>
    Task SetAsync(
        TCacheKey key,
        TCacheItem value,
        DistributedCacheEntryOptions? options = null,
        CancellationToken token = default
    );

    /// <summary>
    /// redis 多个添加
    /// </summary>
    /// <param name="items">redis keys</param>
    /// <param name="options">Redis设置</param>
    void SetMany(
        IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items,
        DistributedCacheEntryOptions? options = null
    );

    /// <summary>
    /// redis 多个添加
    /// </summary>
    /// <param name="items">redis keys</param>
    /// <param name="options">Redis设置</param>
    Task SetManyAsync(
        IEnumerable<KeyValuePair<TCacheKey, TCacheItem>> items,
        DistributedCacheEntryOptions? options = null,
        CancellationToken token = default
    );

    /// <summary>
    /// redis 刷新
    /// </summary>
    /// <param name="key">redis key</param>
    void Refresh(
        TCacheKey key
    );

    /// <summary>
    /// redis 刷新
    /// </summary>
    /// <param name="key">redis key</param>
    Task RefreshAsync(
        TCacheKey key,
        CancellationToken token = default
    );

    /// <summary>
    /// redis 刷新
    /// </summary>
    /// <param name="keys">redis keys</param>
    void RefreshMany(
        IEnumerable<TCacheKey> keys
    );

    /// <summary>
    /// redis 刷新
    /// </summary>
    /// <param name="keys">redis keys</param>
    Task RefreshManyAsync(
        IEnumerable<TCacheKey> keys,
        CancellationToken token = default
    );

    /// <summary>
    /// redis 删除
    /// </summary>
    /// <param name="key">redis key</param>
    void Remove(
        TCacheKey key
    );

    /// <summary>
    /// redis 删除
    /// </summary>
    /// <param name="key">redis keys</param>
    Task RemoveAsync(
        TCacheKey key,
        CancellationToken token = default
    );

    /// <summary>
    /// redis 删除
    /// </summary>
    /// <param name="keys">redis keys</param>
    void RemoveMany(
        IEnumerable<TCacheKey> keys
    );

    /// <summary>
    /// redis 删除
    /// </summary>
    /// <param name="keys">redis keys</param>
    Task RemoveManyAsync(
        IEnumerable<TCacheKey> keys,
        CancellationToken token = default
    );
}
